﻿/*
Project Name : Menfram
Module Name  : Menfram
Date  : 07/06/2013
responsible : Mateus Neto
Obs  : The license of this software is Mozilla Public License 1.1 
contact : mentrixmax@gmail.com
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Menfram.Entity.Interface;
using Menfram.DAL.Reflection;
using System.Collections;
using System.Reflection;
using System.Data.Common;

namespace Menfram.Reflection
{

    /// <summary>
    /// Class that uses reflection to discover the fields and attributes of a class.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Configurations<T>
    {

        /// <summary>
        /// Method with read the class and return the name of atributes 
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        public static Table getTableConfiguration(Type e)
        {
            System.Attribute[] attrs = System.Attribute.GetCustomAttributes(e, typeof(Table));
            var lowNums = from n in attrs select ((Table)n);
            return lowNums.Single();
        }
        /// <summary>
        /// Method with read the class and return the hashtable filled witch value and key
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public static Hashtable getFildConfiguration(T t)
        {
            Hashtable hs = new Hashtable();
            PropertyInfo[] list = t.GetType().GetProperties();
            foreach (PropertyInfo p in list)
            {
                object[] attributes = p.GetCustomAttributes(typeof(Field), false);
                foreach (object attribute in attributes)
                {
                    Field ad = (Field)attribute;
                    object retor = getProperty(t, p.Name);
                    if (retor != null)
                    {
                        hs.Add(ad.FieldName, retor);
                    }
                }
            }
            return hs;
        }

        /// <summary>
        /// Method with get the value of the atribute of the object
        /// </summary>
        /// <param name="a"></param>
        /// <param name="prop"></param>
        /// <returns></returns>
        public static object getProperty(T a, String prop)
        {
            PropertyInfo propriedade = null;
            propriedade = a.GetType().GetProperty(prop);
            return propriedade.GetValue(a, null);
        }

        /// <summary>
        /// Method with put the value of the atribute in the object.
        /// </summary>
        /// <param name="pInfo"></param>
        /// <param name="propertyName"></param>
        /// <param name="propertyValue"></param>
        /// <param name="objectToSetValue"></param>
        private static void setProperty(PropertyInfo pInfo, string propertyName, object propertyValue, object objectToSetValue)
        {
            System.Type pType = pInfo.PropertyType;
            if (pType == typeof(string))
                pInfo.SetValue(objectToSetValue, propertyValue, null);
            else if (pType == typeof(bool))
                pInfo.SetValue(objectToSetValue, Convert.ToBoolean(propertyValue), null);
            else if (pType == typeof(int))
                pInfo.SetValue(objectToSetValue, Convert.ToInt32(propertyValue), null);
            else if (pType == typeof(int?))
                pInfo.SetValue(objectToSetValue, Convert.ToInt32(propertyValue), null);
            else if (pType == typeof(DateTime?))
                pInfo.SetValue(objectToSetValue, Convert.ToDateTime(propertyValue), null);
            else if (pType == typeof(DBNull))
                pInfo.SetValue(objectToSetValue, null, null);
        }
        /// <summary>
        /// Method with filled the copy te data of the databases to entity
        /// </summary>
        /// <param name="db"></param>
        /// <param name="nameObject"></param>
        /// <returns></returns>
        public static T getEntityFilled(DbDataReader db, string nameObject)
        {
            System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly(typeof(T));
            T valor = (T)assembly.CreateInstance(nameObject);

            PropertyInfo[] list = valor.GetType().GetProperties();
            foreach (PropertyInfo p in list)
            {
                object[] attributes = p.GetCustomAttributes(typeof(Field), false);
                foreach (object attribute in attributes)
                {
                    Field ad = (Field)attribute;
                    try
                    {
                        setProperty(p, p.Name, db[ad.FieldName], valor);
                    }
                    catch { 
                    }
                }
            }
            return valor;
        }
    }
}
